﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DesktopShare
{
    public class FullScreenHelper
    {
        bool m_bFullScreen = false;
        IntPtr m_OldWndParent = IntPtr.Zero;
        WINDOWPLACEMENT m_OldWndPlacement = new WINDOWPLACEMENT();
        Control m_control = null;

        public FullScreenHelper(Control c)
        {
            m_control = c;
        }
        public struct POINT
        {
            int x;
            int y;
        };
        public struct RECT
        {
            public int left;
            public int top;
            public int right;
            public int bottom;
        };
        //锁定指定窗口，禁止它更新。同时只能有一个窗口处于锁定状态。锁定指定窗口，禁止它更新。同时只能有一个窗口处于锁定状态
        [DllImport("User32.dll")]
        public static extern bool LockWindowUpdate(IntPtr hWndLock);

        //函数来设置弹出式窗口，层叠窗口或子窗口的父窗口。新的窗口与窗口必须属于同一应用程序
        [DllImport("User32.dll")]
        public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

        //函数设置指定窗口的显示状态和恢复，最大化，最小化位置。函数功能： 函及原型   
        [DllImport("User32.dll")]
        public static extern bool SetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);

        //函数将创建指定窗口的线程设置到前台，并且激活该窗口。键盘输入转向该窗口，并为用户改各种可视的记号
        [DllImport("User32.dll")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);

        //该函数返回桌面窗口的句柄。桌面窗口覆盖整个屏幕。桌面窗口是一个要在其上绘制所有的图标和其他窗口的区域
        [DllImport("User32.dll")]
        public static extern IntPtr GetDesktopWindow();

        //函数名。该函数返回指定窗口的显示状态以及被恢复的、最大化的和最小化的窗口位置
        [DllImport("User32.dll")]
        public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);

        //是用于得到被定义的系统数据或者系统配置信息的一个专有名词  
        [DllImport("User32.dll")]
        public static extern int GetSystemMetrics(int nIndex);

        [DllImport("user32.dll", EntryPoint = "GetParent", SetLastError = true)]
        public static extern IntPtr GetParent(IntPtr hWnd);
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int Width, int Height, int flags);
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern System.IntPtr GetForegroundWindow();
        [DllImport("user32")]
        public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
        [DllImport("user32.dll")]
        public static extern uint ScreenToClient(IntPtr hwnd, ref POINT p);
        public void FullScreen(bool flag)
        {
            m_bFullScreen = flag;
            if (!m_bFullScreen)
            {
                LockWindowUpdate(m_control.Handle);
                SetParent(m_control.Handle, m_OldWndParent);
                SetWindowPlacement(m_control.Handle, ref m_OldWndPlacement);
                SetForegroundWindow(m_OldWndParent);
                LockWindowUpdate(IntPtr.Zero);
            }
            else
            {
                GetWindowPlacement(m_control.Handle, ref m_OldWndPlacement);
                int nScreenWidth = GetSystemMetrics(0);
                int nScreenHeight = GetSystemMetrics(1);
                m_OldWndParent = GetParent(m_control.Parent.Handle);
                SetParent(m_control.Handle, GetDesktopWindow());
                WINDOWPLACEMENT wp1 = new WINDOWPLACEMENT();
                wp1.length = (uint)Marshal.SizeOf(wp1);
                wp1.showCmd = 1;
                wp1.rcNormalPosition.left = 0;
                wp1.rcNormalPosition.top = 0;
                wp1.rcNormalPosition.right = nScreenWidth;
                wp1.rcNormalPosition.bottom = nScreenHeight;
                SetWindowPlacement(m_control.Handle, ref wp1);
                SetForegroundWindow(GetDesktopWindow());
                SetForegroundWindow(m_control.Handle);
            }
            m_bFullScreen = !m_bFullScreen;
        }
        public struct WINDOWPLACEMENT
        {
            public uint length;
            public uint flags;
            public uint showCmd;
            public POINT ptMinPosition;
            public POINT ptMaxPosition;
            public RECT rcNormalPosition;
        };
    }
}
